home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 November / CPNL0711.ISO / boekhoud / finan / BADGER finance v1.0 beta 2.exe / xampplite / phpMyAdmin / libraries / export / pdf.php < prev    next >
PHP Script  |  2006-01-17  |  12KB  |  403 lines

  1. <?php
  2. /* $Id: pdf.php,v 1.3 2006/01/17 17:03:02 cybot_tm Exp $ */
  3. // vim: expandtab sw=4 ts=4 sts=4:
  4.  
  5. /**
  6.  * Produce a PDF report (export) from a query 
  7.  */
  8.  
  9.  
  10. define('FPDF_FONTPATH', './libraries/fpdf/font/');
  11. //if ($charset == 'utf-8') {
  12.     define('PMA_PDF_FONT', 'FreeSans');
  13.     require_once('./libraries/fpdf/ufpdf.php');
  14.     class PMA_FPDF extends UFPDF
  15.     {
  16.     };
  17. //} else {
  18. //    define('PMA_PDF_FONT', 'Arial');
  19. //    require_once('./libraries/fpdf/fpdf.php');
  20. //    class PMA_FPDF extends FPDF {
  21. //    };
  22. //}
  23.  
  24.  
  25. // Adapted from a LGPL script by Philip Clarke
  26.  
  27. class PMA_PDF extends PMA_FPDF 
  28. {
  29.     var $tablewidths;
  30.     var $headerset;
  31.     var $footerset;
  32.  
  33.     // overloading of a fpdf function:
  34.     function _beginpage($orientation) 
  35.     {
  36.         $this->page++;
  37.         // solved the problem of overwriting a page, if it already exists
  38.         if (!isset($this->pages[$this->page])) {
  39.             $this->pages[$this->page] = '';
  40.         }
  41.         $this->state = 2;
  42.         $this->x = $this->lMargin;
  43.         $this->y = $this->tMargin;
  44.         $this->lasth = 0;
  45.         $this->FontFamily = '';
  46.     
  47.         //Page orientation
  48.         if (!$orientation) {
  49.             $orientation = $this->DefOrientation;
  50.         } else {
  51.             $orientation = strtoupper($orientation{0});
  52.             if ($orientation != $this->DefOrientation) {
  53.                 $this->OrientationChanges[$this->page] = true;
  54.             }
  55.         }
  56.         if ($orientation != $this->CurOrientation) {
  57.             //Change orientation
  58.             if ($orientation == 'P') {
  59.                 $this->wPt = $this->fwPt;
  60.                 $this->hPt = $this->fhPt;
  61.                 $this->w = $this->fw;
  62.                 $this->h = $this->fh;
  63.             } else {
  64.                 $this->wPt = $this->fhPt;
  65.                 $this->hPt = $this->fwPt;
  66.                 $this->w = $this->fh;
  67.                 $this->h = $this->fw;
  68.             }
  69.             $this->PageBreakTrigger = $this->h - $this->bMargin;
  70.             $this->CurOrientation = $orientation;
  71.         }
  72.     }
  73.  
  74.     function Header() 
  75.     {
  76.         global $maxY;
  77.  
  78.         // Check if header for this page already exists
  79.         if (!isset($this->headerset[$this->page])) {
  80.             $fullwidth = 0;
  81.             foreach ($this->tablewidths as $width) {
  82.                 $fullwidth += $width;
  83.             }
  84.             $this->SetY(($this->tMargin) - ($this->FontSizePt/$this->k)*2);
  85.             $this->cellFontSize = $this->FontSizePt ;
  86.             $this->SetFont(PMA_PDF_FONT, '', ($this->titleFontSize ? $this->titleFontSize : $this->FontSizePt));
  87.             $this->Cell(0, $this->FontSizePt, $this->titleText, 0, 1, 'C');
  88.             $l = ($this->lMargin);
  89.             $this->SetFont(PMA_PDF_FONT, '', $this->cellFontSize);
  90.             foreach ($this->colTitles as $col => $txt) {
  91.                 $this->SetXY($l, ($this->tMargin));
  92.                 $this->MultiCell($this->tablewidths[$col], $this->FontSizePt, $txt);
  93.                 $l += $this->tablewidths[$col] ;
  94.                 $maxY = ($maxY < $this->getY()) ? $this->getY() : $maxY ;
  95.             }
  96.             $this->SetXY($this->lMargin, $this->tMargin);
  97.             $this->setFillColor(200, 200, 200);
  98.             $l = ($this->lMargin);
  99.             foreach ($this->colTitles as $col => $txt) {
  100.                 $this->SetXY($l, $this->tMargin);
  101.                 $this->cell($this->tablewidths[$col], $maxY-($this->tMargin), '', 1, 0, 'L', 1);
  102.                 $this->SetXY($l, $this->tMargin);
  103.                 $this->MultiCell($this->tablewidths[$col], $this->FontSizePt, $txt, 0, 'C');
  104.                 $l += $this->tablewidths[$col];
  105.             }
  106.             $this->setFillColor(255, 255, 255);
  107.             // set headerset
  108.             $this->headerset[$this->page] = 1;
  109.         }
  110.  
  111.         $this->SetY($maxY);
  112.     }
  113.  
  114.     function Footer() 
  115.     {
  116.     // Check if footer for this page already exists
  117.         if (!isset($this->footerset[$this->page])) {
  118.             $this->SetY(-15);
  119.             //Page number
  120.             $this->Cell(0, 10, $GLOBALS['strPageNumber'] .' '.$this->PageNo() .'/{nb}', 'T', 0, 'C');
  121.  
  122.         // set footerset
  123.             $this->footerset[$this->page] = 1;
  124.         }
  125.     }
  126.  
  127.     function morepagestable($lineheight=8) 
  128.     {
  129.         // some things to set and 'remember'
  130.         $l = $this->lMargin;
  131.         $startheight = $h = $this->GetY();
  132.         $startpage = $currpage = $this->page;
  133.  
  134.         // calculate the whole width
  135.         $fullwidth = 0;
  136.         foreach ($this->tablewidths as $width) {
  137.             $fullwidth += $width;
  138.         }
  139.  
  140.         // Now let's start to write the table
  141.         $row = 0;
  142.         $tmpheight = array();
  143.         $maxpage = 0;
  144.  
  145.         while ($data = PMA_DBI_fetch_row($this->results)) {
  146.             $this->page = $currpage;
  147.             // write the horizontal borders
  148.             $this->Line($l, $h, $fullwidth+$l, $h);
  149.             // write the content and remember the height of the highest col
  150.             foreach ($data as $col => $txt) {
  151.                 $this->page = $currpage;
  152.                 $this->SetXY($l, $h);
  153.                 $this->MultiCell($this->tablewidths[$col], $lineheight, $txt, 0, $this->colAlign[$col]);
  154.  
  155.                 $l += $this->tablewidths[$col];
  156.  
  157.                 if (!isset($tmpheight[$row.'-'.$this->page])) {
  158.                     $tmpheight[$row.'-'.$this->page] = 0;
  159.                 }
  160.                 if ($tmpheight[$row.'-'.$this->page] < $this->GetY()) {
  161.                     $tmpheight[$row.'-'.$this->page] = $this->GetY();
  162.                 }
  163.                 if ($this->page > $maxpage) {
  164.                     $maxpage = $this->page;
  165.                 }
  166.                 unset($data[$col]);
  167.             }
  168.  
  169.             // get the height we were in the last used page
  170.             $h = $tmpheight[$row.'-'.$maxpage];
  171.             // set the "pointer" to the left margin
  172.             $l = $this->lMargin;
  173.             // set the $currpage to the last page
  174.             $currpage = $maxpage;
  175.             unset($data[$row]);
  176.             $row++;
  177.         }
  178.         // draw the borders
  179.         // we start adding a horizontal line on the last page
  180.         $this->page = $maxpage;
  181.         $this->Line($l, $h, $fullwidth+$l, $h);
  182.         // now we start at the top of the document and walk down
  183.         for ($i = $startpage; $i <= $maxpage; $i++) {
  184.             $this->page = $i;
  185.             $l = $this->lMargin;
  186.             $t = ($i == $startpage) ? $startheight : $this->tMargin;
  187.             $lh = ($i == $maxpage) ? $h : $this->h-$this->bMargin;
  188.             $this->Line($l, $t, $l, $lh);
  189.             foreach ($this->tablewidths as $width) {
  190.                 $l += $width;
  191.                 $this->Line($l, $t, $l, $lh);
  192.             }
  193.         }
  194.         // set it to the last page, if not it'll cause some problems
  195.         $this->page = $maxpage;
  196.     }
  197.  
  198.  
  199.     function mysql_report($query, $attr = array())
  200.     {
  201.         foreach ($attr as $key => $val){
  202.             $this->$key = $val ;
  203.         }
  204.  
  205.         // Pass 1 for column widths
  206.         // TODO: force here a LIMIT to speed up pass 1 ?
  207.         $this->results = PMA_DBI_query($query, null, PMA_DBI_QUERY_UNBUFFERED);
  208.         $this->numFields  = PMA_DBI_num_fields($this->results);
  209.         $this->fields = PMA_DBI_get_fields_meta($this->results);
  210.  
  211.         // if column widths not set
  212.         if (!isset($this->tablewidths)){
  213.  
  214.             // starting col width
  215.             $this->sColWidth = ($this->w - $this->lMargin - $this->rMargin) / $this->numFields;
  216.  
  217.             // loop through results header and set initial col widths/ titles/ alignment
  218.             // if a col title is less than the starting col width / reduce that column size
  219.             for ($i=0; $i < $this->numFields; $i++){
  220.                 $stringWidth = $this->getstringwidth($this->fields[$i]->name) + 6 ;
  221.                 // set any column titles less than the start width to the column title width
  222.                 if (($stringWidth) < $this->sColWidth){
  223.                     $colFits[$i] = $stringWidth ;
  224.                 }
  225.                 $this->colTitles[$i] = $this->fields[$i]->name;
  226.                 switch ($this->fields[$i]->type){
  227.                 case 'int':
  228.                     $this->colAlign[$i] = 'R';
  229.                     break;
  230.                 default:
  231.                     $this->colAlign[$i] = 'L';
  232.                 }
  233.             }
  234.  
  235.             // loop through the data, any column whose contents is bigger i
  236.             // that the col size is resized
  237.             while ($row = PMA_DBI_fetch_row($this->results)) {
  238.                 foreach ($colFits as $key => $val) {
  239.                     $stringWidth = $this->getstringwidth($row[$key]) + 6 ;
  240.                     if ($stringWidth > $this->sColWidth) {
  241.                     // any col where row is bigger than the start width is now discarded
  242.                     unset($colFits[$key]);
  243.                     } else {
  244.                     // if text is not bigger than the current column width setting enlarge the column
  245.                         if ($stringWidth > $val) {
  246.                             $colFits[$key] = ($stringWidth) ;
  247.                         }
  248.                     }
  249.                 }
  250.             }
  251.  
  252.             $totAlreadyFitted = 0;
  253.             foreach ($colFits as $key => $val){
  254.                 // set fitted columns to smallest size
  255.                 $this->tablewidths[$key] = $val;
  256.                 // to work out how much (if any) space has been freed up
  257.                 $totAlreadyFitted += $val;
  258.             }
  259.  
  260.             $surplus = (sizeof($colFits) * $this->sColWidth) - $totAlreadyFitted;
  261.             for ($i=0; $i < $this->numFields; $i++) {
  262.                 if (!in_array($i, array_keys($colFits))) {
  263.                     $this->tablewidths[$i] = $this->sColWidth + ($surplus / ($this->numFields - sizeof($colFits)));
  264.                 }
  265.             }
  266.  
  267.             ksort($this->tablewidths);
  268.  
  269.         }
  270.  
  271.         PMA_DBI_free_result($this->results);
  272.  
  273.         // Pass 2
  274.  
  275.         $this->results = PMA_DBI_query($query, null, PMA_DBI_QUERY_UNBUFFERED);
  276.         $this->Open();
  277.         $this->setY($this->tMargin);
  278.         $this->AddPage();
  279.         $this->morepagestable($this->FontSizePt);
  280.         PMA_DBI_free_result($this->results);
  281.  
  282.     } // end of mysql_report function 
  283.  
  284. } // end of PMA_PDF class
  285.  
  286. /**
  287.  * Outputs comment
  288.  *
  289.  * @param   string      Text of comment
  290.  *
  291.  * @return  bool        Whether it suceeded
  292.  */
  293. function PMA_exportComment($text) 
  294. {
  295.     return TRUE;
  296. }
  297.  
  298. /**
  299.  * Outputs export footer
  300.  *
  301.  * @return  bool        Whether it suceeded
  302.  *
  303.  * @access  public
  304.  */
  305. function PMA_exportFooter() 
  306. {
  307.     return TRUE;
  308. }
  309.  
  310. /**
  311.  * Outputs export header
  312.  *
  313.  * @return  bool        Whether it suceeded
  314.  *
  315.  * @access  public
  316.  */
  317. function PMA_exportHeader() 
  318. {
  319.     return TRUE;
  320. }
  321.  
  322. /**
  323.  * Outputs database header
  324.  *
  325.  * @param   string      Database name
  326.  *
  327.  * @return  bool        Whether it suceeded
  328.  *
  329.  * @access  public
  330.  */
  331. function PMA_exportDBHeader($db) 
  332. {
  333.     return TRUE;
  334. }
  335.  
  336. /**
  337.  * Outputs database footer
  338.  *
  339.  * @param   string      Database name
  340.  *
  341.  * @return  bool        Whether it suceeded
  342.  *
  343.  * @access  public
  344.  */
  345. function PMA_exportDBFooter($db) 
  346. {
  347.     return TRUE;
  348. }
  349.  
  350. /**
  351.  * Outputs create database database
  352.  *
  353.  * @param   string      Database name
  354.  *
  355.  * @return  bool        Whether it suceeded
  356.  *
  357.  * @access  public
  358.  */
  359. function PMA_exportDBCreate($db) 
  360. {
  361.     return TRUE;
  362. }
  363.  
  364. /**
  365.  * Outputs the content of a table in PDF format
  366.  *
  367.  * @param   string      the database name
  368.  * @param   string      the table name
  369.  * @param   string      the end of line sequence
  370.  * @param   string      the url to go back in case of error
  371.  * @param   string      SQL query for obtaining data
  372.  *
  373.  * @return  bool        Whether it suceeded
  374.  *
  375.  * @access  public
  376.  */
  377. function PMA_exportData($db, $table, $crlf, $error_url, $sql_query) 
  378. {
  379.     global $what;
  380.     global $pdf_report_title;
  381.  
  382.     // TODO: user-defined page orientation, paper size
  383.     $pdf = new PMA_PDF('L', 'pt', 'A3');
  384.  
  385.     $pdf->AddFont('FreeSans', '', 'FreeSans.php');
  386.     $pdf->AddFont('FreeSans', 'B', 'FreeSansBold.php');
  387.     $pdf->SetFont(PMA_PDF_FONT, '', 11.5);
  388.     $pdf->AliasNbPages();
  389.     $attr=array('titleFontSize' => 18, 'titleText' => $pdf_report_title);
  390.     $pdf->mysql_report($sql_query, $attr);
  391.  
  392.     // instead of $pdf->Output():
  393.     if ($pdf->state < 3) {
  394.         $pdf->Close();
  395.     }
  396.     if (!PMA_exportOutputHandler($pdf->buffer)) {
  397.         return FALSE;
  398.     }
  399.  
  400.     return TRUE;
  401. } // end of the 'PMA_exportData()' function
  402. ?>
  403.